package com.fay.mymiaosha.controller;

import com.fay.mymiaosha.controller.vo.UserVO;
import com.fay.mymiaosha.exception.BizException;
import com.fay.mymiaosha.response.CommonReturnType;
import com.fay.mymiaosha.response.EmBizError;
import com.fay.mymiaosha.service.IUserService;
import com.fay.mymiaosha.service.model.UserModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/**
 * @Title:
 * @Description:
 * @Author Fay Wang
 * @Date 2022/3/14 22:17
 * @Version 1.0
 */
@Slf4j
@RestController("user")
@RequestMapping("/user")
@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")
public class UserController extends BaseController {

    @Autowired
    private IUserService userServiceImpl;

    @Autowired
    private HttpServletRequest httpServletRequest;

    /**
     * login for user
     * @param telephone
     * @param password
     * @return
     * @throws BizException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping("/login")
    @RequestMapping(value = "/login", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    public CommonReturnType register(@RequestParam(name = "telephone") String telephone,
                                     @RequestParam(name = "password") String password) throws BizException, NoSuchAlgorithmException {

        // arguments validation
        if (StringUtils.isEmpty(telephone) || StringUtils.isEmpty(password)) {
            throw new BizException(EmBizError.PARAMETER_VALIDATION_ERROR);
        }

        // login validation
        UserModel userModel = userServiceImpl.validateLogin(telephone, this.EncodeByMd5(password));

        // save ticket
        this.httpServletRequest.getSession().setAttribute("IS_LOGIN", true);
        this.httpServletRequest.getSession().setAttribute("LOGIN_USER", userModel);

        return CommonReturnType.create(null);
    }


    /**
     *  register for user
     * @param telephone
     * @param otpCode
     * @param name
     * @param password
     * @param gender
     * @param age
     * @return CommonReturnType
     * @throws BizException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping("/register")
    @RequestMapping(value = "/register",method = {RequestMethod.POST},consumes = {CONTENT_TYPE_FORMED})
    public CommonReturnType register(@RequestParam(name = "telephone")String telephone,
                                     @RequestParam(name = "otpCode")String otpCode,
                                     @RequestParam(name = "name")String name,
                                     @RequestParam(name = "password")String password,
                                     @RequestParam(name = "gender")Byte gender,
                                     @RequestParam(name = "age")Integer age) throws BizException, NoSuchAlgorithmException {
        // check match or not
        String inSessionOtpCode = (String) this.httpServletRequest.getSession().getAttribute(telephone);
        if (!StringUtils.equals(otpCode, inSessionOtpCode)) {
            throw new BizException(EmBizError.PARAMETER_VALIDATION_ERROR, "短信验证码不符合");
        }
        // convert to model
        UserModel userModel = new UserModel();
        userModel.setTelephone(telephone);
        userModel.setThirdPartyCode("byPhone");
        userModel.setName(name);
        // Java自带的md5加密方式 是只支持16位的md5加密
        userModel.setEncrptPassword(EncodeByMd5(password));
        userModel.setGender(gender);
        userModel.setAge(age);
        // register
        userServiceImpl.register(userModel);
        return CommonReturnType.create(null);
    }

    /**
     * get otp code when registering
     * @param telephone
     * @return
     */
    @GetMapping("/getotp")
    public CommonReturnType getOtp(@RequestParam(name = "telephone") String telephone) {
        // generate random code
        Random random = new Random();
        int randomInt = random.nextInt(99999);
        randomInt += 100000;
        String otpCode = String.valueOf(randomInt);

        // save code into session
        httpServletRequest.setAttribute(telephone, otpCode);
        log.info("telephone=" + telephone + " ,otpCode=" + otpCode);
        return CommonReturnType.create(null);
    }

    /**
     * list user_info
     * @param id
     * @return
     * @throws BizException
     */
    @GetMapping(value = "/get")
    public CommonReturnType getUser(@RequestParam(name = "id") Integer id) throws BizException {
        UserModel userModel = userServiceImpl.getUserById(id);
        if (userModel == null) {
            throw new BizException(EmBizError.USER_NOT_EXIST);
        }
        UserVO userVO = convertFromModel(userModel);
        return CommonReturnType.create(userVO);
    }

    /**
     * convert to model from vo
     * @param userModel
     * @return
     */
    private UserVO convertFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userModel, userVO);
        return userVO;
    }

    /**
     *  encoded password by md5
     * @param str password
     * @return encoded password
     * @throws NoSuchAlgorithmException
     */
    private String EncodeByMd5(String str) throws NoSuchAlgorithmException {
        // 1. choose to calculate methods
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        BASE64Encoder base64Encoder = new BASE64Encoder();
        // 2. encoded the string
        return base64Encoder.encode(md5.digest(str.getBytes(StandardCharsets.UTF_8)));
    }
}
